package com.bbva.kyfb.kyfbutils.invoker;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import com.bbva.jee.arq.spring.core.gce.ExcepcionEjecucionAplicacion;
import com.bbva.kyfb.kyfbdto.firmas.bo.AsuntoInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.DatosPAU;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroPdteFirma;
import com.bbva.kyfb.kyfbdto.firmas.bo.ReferenciaInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.ServicioAsuntoFirmable;
import com.bbva.kyfb.kyfbdto.firmas.errores.Errores_kyfb_servicios;
import com.bbva.kyfb.kyfbutils.constantes.ConstantesFO;
import com.bbva.kyfb.kyfbutils.constantes.UtilFO;
import com.bbva.kygu.clientcontractws.beans.AServicioAsuntosType;
import com.bbva.kygu.clientcontractws.beans.AsuntoType;
import com.bbva.kygu.clientcontractws.beans.EmpresaRelacionadaType;
import com.bbva.kygu.clientcontractws.beans.RespuestaCargarCashType;
import com.bbva.kygu.clientcontractws.beans.RespuestaEmpresaRelType;
import com.bbva.kygu.clientcontractws.beans.RespuestaEmpresaType;
import com.bbva.kygu.clientcontractws.beans.RespuestaServicioCtxType;
import com.bbva.kygu.clientcontractws.beans.RespuestaUsuarioUniqType;
import com.bbva.kygu.clientcontractws.beans.ServicioAsuntosType;
import com.bbva.kygu.clientcontractws.beans.ServicioCtxType;
import com.bbva.kytv.dto.kygu.UsuarioEmpresaDTO;
import com.bbva.kytv.interfaces.kygu.IGestionLimite;
import com.bbva.kytv.interfaces.kygu.IInformacionEmpresaInvoker;
import com.bbva.kytv.interfaces.kygu.IInformacionUsuarios;
import com.bbva.kytv.interfaces.kygu.IModificacionDatosBasicos;
import com.bbva.kytv.util.exception.KYTVException;

/**
 * The Class ServicioFirmasBoClientsUtil.
 */

public class ServicioFirmasInvokerComun {

	//private static final I18nLog LOG = I18nLogFactory.getLogI18n(ServicioFirmasInvokerComun.class);

	private static final String[] ASUN_OPT1 = new String[] { "ACO", "ACR", "ACM", "AAC", "CPA", "CPS", "CFV" };
	private static final String[] ASUN_OPT2 = new String[] { "GDL", "GDP", "GLD", "GPD" };
	private static final String[] ASUN_OPT3 = new String[] { "GDS", "ACP", "JBE", "SFI", "MCP", "MRC",
		"IDC", "DOO", "JBR", "CPR", "MCR", "CVP", "RDM", "RDJ", "RDC", "RDO" };
	private static final String[] ASUN_OPT4 = new String[] { "FAA", "FPN", "FRN" };
	private static final String[] ASUN_OPT5 = new String[] { "FAI", "FPI", "FSI", "TRR", "FRT" };
	private static final String[] ASUN_OPT6 = new String[] { "CVV", "ACV", "MCV", "MCW", "ACC", "MCC", "CVC", "CVW" };
	private static final String[] ASUN_OPT7 = new String[] { "JU1", "EFE", "TRI", "ISG", "PSP", "PSC",
		"PIP", "PIC", "BTJ", "GMS", "CHP", "VIV", "VVE", "DSD", "CDP" };

	static{ //Si no el binary search no funciona adecuadamente
		Arrays.sort(ASUN_OPT1);
		Arrays.sort(ASUN_OPT2);
		Arrays.sort(ASUN_OPT3);
		Arrays.sort(ASUN_OPT4);
		Arrays.sort(ASUN_OPT5);
		Arrays.sort(ASUN_OPT6);
		Arrays.sort(ASUN_OPT7);
	}




	/**
	 * Checks for auditores empresa.
	 * 
	 * @param fichero
	 *            the fichero
	 * @param file
	 *            the file
	 * @param codClienteCash
	 *            the cod cliente cash
	 * @return true, if successful
	 * @throws ExcepcionEjecucionAplicacion
	 *             the excepcion ejecucion aplicacion
	 */
	public boolean hasAuditoresEmpresa(final FicheroPdteFirma fichero,
			final FicheroInfo file, final String codClienteCash)
					throws ExcepcionEjecucionAplicacion {
		return !CollectionUtils.isEmpty(getAuditoresReferencia(fichero, file,
				codClienteCash));
	}

	/**
	 * Gets the empresas.
	 * 
	 * @param canal
	 *            the canal
	 * @param codBancoInt
	 *            the cod banco int
	 * @param referencia
	 *            the referencia
	 * @return the empresas
	 * @throws ExcepcionEjecucionAplicacion
	 *             the excepcion ejecucion aplicacion
	 */
	public List<ReferenciaInfo> getEmpresas(final String canal,
                       final String codBancoInt, final String referencia)
                                       throws ExcepcionEjecucionAplicacion {
               final List<ReferenciaInfo> refrenciasAsociadas = new ArrayList<ReferenciaInfo>();
               ReferenciaInfo ref = null;
               final String codCanal = canal;
               final int codBancoInterno = Integer.parseInt(codBancoInt);
               final String codEmpresa = referencia;
               final int codBancoProd = Integer.MIN_VALUE;
               final int codProducto = Integer.MIN_VALUE;
               final int codSubproducto = Integer.MIN_VALUE;
               //final String codCanalRel = "";
               final int codBancoInternoRel = Integer.MIN_VALUE;
               final String codEmpresaRel = "";
               final int codBancoProdRel = Integer.MIN_VALUE;
               final int codProductoRel = Integer.MIN_VALUE;
               final int codSubproductoRel = Integer.MIN_VALUE;
               RespuestaEmpresaRelType lstRelProdEmp = null;

               try {
                       final IInformacionEmpresaInvoker infoEmpresa = (IInformacionEmpresaInvoker) InvokerUtils
                                       .getBeanInvoker(ConstantesFO.VAR_INFO_EMPRESA,
                                                       IInformacionEmpresaInvoker.class);
                       lstRelProdEmp = infoEmpresa.listarRelProdEmpresa(Integer.parseInt(codCanal),
                                       codEmpresa, codBancoInterno, codBancoProd, codProducto,
                                       codSubproducto, null, codEmpresaRel, codBancoInternoRel,
                                       codBancoProdRel, codProductoRel, codSubproductoRel);
               } catch (final KYTVException e) {
                       throw new ExcepcionEjecucionAplicacion(
                                       Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
               }

               if (lstRelProdEmp != null && lstRelProdEmp.getListaEmpresaRel() != null && lstRelProdEmp.getListaEmpresaRel().getEmpresaRel() != null) {
                       for (final EmpresaRelacionadaType empresa : lstRelProdEmp.getListaEmpresaRel().getEmpresaRel()) {
                               ref = new ReferenciaInfo();
                               ref.setCodBancoInt(Integer.toString(empresa.getCodBancoInternoRel()));
                               ref.setCodCanal(empresa.getCodCanalRel());
                               ref.setReferencia(empresa.getCodEmpresaRel());
                               refrenciasAsociadas.add(ref);
                       }
               }
               return refrenciasAsociadas;
       }

	/**
	 * Gets the servicios asuntos by empresa.
	 * 
	 * @param referenciasAsociadas
	 *            the referencias asociadas
	 * @return the servicios asuntos by empresa
	 * @throws ExcepcionEjecucionAplicacion
	 *             the excepcion ejecucion aplicacion
	 */
	public List<String> getServiciosAsuntosByEmpresa(
			final List<ReferenciaInfo> referenciasAsociadas)
					throws ExcepcionEjecucionAplicacion {
		final List<String> listaServicios = new ArrayList<String>();
		String codCanalRel = null;
		int codBancoInternoRel = 0;
		String codEmpresaRel = null;
		final int codBancoProdRel = Integer.MIN_VALUE;
		final int codProductoRel = Integer.MIN_VALUE;
		final int codSubproducto = Integer.MIN_VALUE;
		final String codServicio = "";
		final String asunto = "";
		final String indOrdenanteBeneficiario = "";
		final int bancoAsunto = Integer.MIN_VALUE;
		final String idioma = "";
		final String indObtenerAsuntos = "N";
		final String mostrarOcultosNoPropagables = "";
		final String mostrarRazonSocial = "";
		for (final ReferenciaInfo referencia : referenciasAsociadas) {
			codBancoInternoRel = Integer.parseInt(referencia.getCodBancoInt());
			codCanalRel = referencia.getCodCanal();
			codEmpresaRel = referencia.getReferencia();
			final IInformacionEmpresaInvoker infoEmpresa = (IInformacionEmpresaInvoker) InvokerUtils
					.getBeanInvoker(ConstantesFO.VAR_INFO_EMPRESA,
							IInformacionEmpresaInvoker.class);
			final RespuestaServicioCtxType respuesta = infoEmpresa
					.listarServiciosAsuntos(codCanalRel, codBancoInternoRel,
							codEmpresaRel, codBancoProdRel, codProductoRel,
							codSubproducto, codServicio, asunto,
							indOrdenanteBeneficiario, bancoAsunto, idioma,
							indObtenerAsuntos, mostrarOcultosNoPropagables,
							mostrarRazonSocial);
			for (final ServicioCtxType a : respuesta.getListaServicioCtx()
					.getServicioCtx()) {
				listaServicios.add(a.getCodServicioLocal());
			}
		}

		return listaServicios;
	}

	/**
	 * Gets the auditores referencia host.
	 * 
	 * @param fichero
	 *            the fichero
	 * @param file
	 *            the file
	 * @param codClienteCash
	 *            the cod cliente cash
	 * @return the auditores referencia host
	 */
	public List<UsuarioEmpresaDTO> getUsuariosFirmantesReferenciaHost(
			final FicheroPdteFirma fichero, final FicheroInfo file,
			final String codClienteCash) {

		final String codCanal = file.getCodClienteCash().substring(0, 4);
		final int codBancoInterno = Integer.parseInt(file.getCodClienteCash()
				.substring(4, 8));
		final String codEmpresa = file.getCodClienteCash().substring(8, 16);
		final int codBancoProducto = Integer.parseInt(file.getsBancoProducto());
		final int codSubProducto = Integer.parseInt(file.getsCodSubproducto());
		final int codProducto = Integer.parseInt(file.getsCodProducto());
		List<UsuarioEmpresaDTO> res = null;
		try {
			final IInformacionUsuarios infoUsuarios = (IInformacionUsuarios) InvokerUtils
					.getBeanInvoker(ConstantesFO.VAR_LISTA_USUARIO,
							IInformacionUsuarios.class);
			res = infoUsuarios.listarUsuariosPorTipoPerfil(codCanal,
					codBancoInterno, codEmpresa, codBancoProducto, codProducto,
					codSubProducto, "", "S", "", "", "");
			RespuestaCargarCashType eurasia = infoUsuarios.cargarContextoCashEurasia(codCanal, codBancoInterno, "20027999", "FO", "", "");

			
		} catch (final KYTVException e) {
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
		}

		return res;
	}
	
	//TODO: pendiente
	public RespuestaCargarCashType cargarContextoCashEurasia(final FicheroInfo file) {
		final String codCanal = file.getCodClienteCash().substring(0, 4);
		final int codBancoInterno = Integer.parseInt(file.getCodClienteCash()
				.substring(4, 8));
		
		try {
			final IInformacionUsuarios infoUsuarios = (IInformacionUsuarios) InvokerUtils
					.getBeanInvoker(ConstantesFO.VAR_LISTA_USUARIO,
							IInformacionUsuarios.class);
			
			//tambien funciona con el usuario DANI
			RespuestaCargarCashType eurasia = infoUsuarios.cargarContextoCashEurasia(codCanal, codBancoInterno, "20027999", "FO", "", "");

			return eurasia;
			
		} catch (final KYTVException e) {
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
		}		
	}

	/**
	 * Gets the asuntos servicio by usuario.
	 * 
	 * @param file
	 *            the file
	 * @return the asuntos servicio by usuario
	 * @throws ExcepcionEjecucionAplicacion
	 *             the excepcion ejecucion aplicacion
	 */
	public ArrayList<ServicioAsuntoFirmable> getAsuntosServicioByUsuario(
			final FicheroInfo file) throws ExcepcionEjecucionAplicacion {
		final String codPerfil = "A";
		ArrayList<ServicioAsuntoFirmable> listaServiciosAsuntos = null;
		final String codCanal = file.getCodClienteCash().substring(0, 4);
		final int codBancoInterno = Integer.parseInt(file.getCodClienteCash()
				.substring(4, 8));
		final String codEmpresa = file.getCodClienteCash().substring(8, 16);
		final int codBancoProducto = Integer.parseInt(file.getsBancoProducto());
		final int codProducto = Integer.parseInt(file.getsCodProducto());
		final int codSubProducto = Integer.parseInt(file.getsCodSubproducto());
		final String codUsuario = file.getsCodUsuario();

		final IGestionLimite gestionLimite = (IGestionLimite) InvokerUtils
				.getBeanInvoker(ConstantesFO.VAR_GESTION_LIMITE,
						IGestionLimite.class);
		com.bbva.kygu.clientcontractws.beans.RespuestaUsuarioServAsuntoType respuesta = null;
		try {
			respuesta = gestionLimite.listarAsuntosFirmaUsuario(codCanal,
					codBancoInterno, codEmpresa, codBancoProducto, codProducto,
					codSubProducto, codUsuario, codPerfil);
		} catch (final KYTVException e) {
			e.printStackTrace();
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
		}
		if (respuesta.getRespuesta().getCodError().equals("0")
				&& respuesta.getListaUsuarioServ() != null
				&& respuesta.getListaUsuarioServ().getUsuarioServAsunto() != null) {
			listaServiciosAsuntos = new ArrayList<ServicioAsuntoFirmable>();
			for (final com.bbva.kygu.clientcontractws.beans.UsuarioServAsuntoType usuServAsu : respuesta
					.getListaUsuarioServ().getUsuarioServAsunto()) {
				ServicioAsuntoFirmable servAsu = null;
				if (usuServAsu != null
						&& usuServAsu.getListaServicioAsuntos() != null) {
					final AServicioAsuntosType servAsuntos = usuServAsu
							.getListaServicioAsuntos();
					if (servAsuntos.getServicioAsuntos() != null) {
						for (final ServicioAsuntosType asunType : servAsuntos
								.getServicioAsuntos()) {
							servAsu = new ServicioAsuntoFirmable();
							servAsu.setTipoServicio(asunType.getCodServicio());
							servAsu.setPoderFirma(asunType.getPoderFirma());
							final ArrayList<AsuntoInfo> asuntos = new ArrayList<AsuntoInfo>();
							if (asunType.getListaAsuntos() != null
									&& asunType.getListaAsuntos().getAsunto() != null) {
								AsuntoInfo asuntoObj;
								for (final AsuntoType asunto : asunType
										.getListaAsuntos().getAsunto()) {
									// servAsu.setValidarAsunto(asunto.getIndUsrAutorizarAsunto());
									// servAsu.setValidarLimite(asunto.getIndUsrAutorizarAsunto());
									asuntoObj = new AsuntoInfo();
									asuntoObj.setAsunto(asunto.getNuAsunto()
											.trim());
									asuntoObj.setDivisa(asunto.getTipoDivisa());
									asuntoObj.setLimite(asunto
											.getLimFirmaAsunto());

									asuntos.add(asuntoObj);
								}
							}
							servAsu.setAsuntos(asuntos);
							listaServiciosAsuntos.add(servAsu);
						}
					}
				}
			}
		} else if (respuesta.getRespuesta().getCodRetorno().equals("GL0201")) {
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.NO_EXISTEN_DATOS_A_LISTAR);
		} else { // TODO: errores especificos FID.
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE);
		}
		return listaServiciosAsuntos;
	}

	/**
	 * Gets the tipo firmante.
	 * 
	 * @param file
	 *            the file
	 * @return the tipo firmante
	 * @throws ExcepcionEjecucionAplicacion
	 *             the excepcion ejecucion aplicacion
	 */
	public String getTipoFirmante(final FicheroInfo file)
			throws ExcepcionEjecucionAplicacion {
		final String codIdioma = "";
		final String codCanal = file.getCodClienteCash().substring(0, 4);
		final int codBancoInterno = Integer.parseInt(file.getCodClienteCash()
				.substring(4, 8));
		final String codEmpresa = file.getCodClienteCash().substring(8, 16);
		final int codProducto = Integer.parseInt(file.getsCodProducto());
		final int codBancoProd = Integer.parseInt(file.getsBancoProducto());
		final int codSubproducto = Integer.parseInt(file.getsCodSubproducto());
		final String codUsuario = file.getsCodUsuario();
		RespuestaUsuarioUniqType respuesta = null;
		com.bbva.kygu.clientcontractws.beans.UsuarioType usuario = null;
		try {
			respuesta = ((IModificacionDatosBasicos) InvokerUtils
					.getBeanInvoker(ConstantesFO.VAR_MODIF_DATOS_BASICOS,
							IModificacionDatosBasicos.class))
							.consultarDatosBasicosUsuario(codCanal, codBancoInterno,
									codEmpresa, codBancoProd, codProducto,
									codSubproducto, codUsuario, codIdioma);
			usuario = respuesta.getUsuario();
		} catch (final KYTVException e) {
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
		}
		return usuario == null ? null : usuario.getTipoFirmante();
	}

	/**
	 * @param canal
	 * @param bancoInterno
	 * @param empresa
	 * @return
	 */
	public String obetenerProductoPibee(final DatosPAU datosPau,
			final String defecto) {
		String producto = defecto;
		if (datosPau != null && !StringUtils.isEmpty(datosPau.getsCanal())
				&& !StringUtils.isEmpty(datosPau.getsBancoInt())
				&& !StringUtils.isEmpty(datosPau.getsReferencia())) {
			final IInformacionEmpresaInvoker infoEmpresa = (IInformacionEmpresaInvoker) InvokerUtils
					.getBeanInvoker(ConstantesFO.VAR_INFO_EMPRESA,
							IInformacionEmpresaInvoker.class);
			try{
				final RespuestaEmpresaType respuesta = infoEmpresa
						.consultarProductoPIBEE(datosPau.getsCanal(),
								Integer.valueOf(datosPau.getsBancoInt()),
								datosPau.getsReferencia());

				if(respuesta != null && respuesta.getEmpresa() != null) {
					producto = respuesta.getEmpresa().getCodProductoPB();
				}else {
					producto = "201";
				}
			} catch (final KYTVException e) {
				throw new ExcepcionEjecucionAplicacion(
						Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
			}
		}
		return producto;
	}

	/**
	 * Gets the auditores referencia.
	 * 
	 * @param fichero
	 *            the fichero
	 * @param file
	 *            the file
	 * @param codClienteCash
	 *            the cod cliente cash
	 * @return the auditores referencia
	 * @throws ExcepcionEjecucionAplicacion
	 *             the excepcion ejecucion aplicacion
	 */
	public List<UsuarioEmpresaDTO> getAuditoresReferencia(
			final FicheroPdteFirma fichero, final FicheroInfo file,
			final String codClienteCash) throws ExcepcionEjecucionAplicacion {
		final String codCanal = file.getCodClienteCash().substring(0, 4);
		final int codBancoInterno = Integer.valueOf(file.getCodClienteCash()
				.substring(4, 8));
		final String codEmpresa = file.getCodClienteCash().substring(8, 16);
		final int codBancoProducto = Integer.valueOf(file.getsBancoProducto());
		final int codSubProducto = Integer.valueOf(file.getsCodSubproducto());
		final int codProducto = Integer.valueOf(file.getsCodProducto());

		List<UsuarioEmpresaDTO> res = null;
		try {
			final IInformacionUsuarios infoUsuarios = (IInformacionUsuarios) InvokerUtils
					.getBeanInvoker(ConstantesFO.VAR_LISTA_USUARIO,
							IInformacionUsuarios.class);
			res = infoUsuarios.listarUsuariosPorTipoPerfil(codCanal,
					codBancoInterno, codEmpresa, codBancoProducto, codProducto,
					codSubProducto, "", "S", UtilFO.USUARIO_AUDITOR, "", "");
		} catch (final KYTVException e) {
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE, e);
		}

		return res;
	}

}
